import { usePermissionStore, useUserStore } from '@/store'
import type { RouteRecordRaw } from 'vue-router'
import NProgress from '@/utils/nprogress'
import router from '@/router'
import { redirectToLogin } from '@/utils/router'
import Storage from '@/utils/Storage'
import { TOKEN_KEY } from '@/utils/constant'
import defaultSettings from '@/utils/settings'

export function setupPermission() {
  // 白名单路由
  const whiteList = ['/login']

  router.beforeEach(async (to, from, next) => {
    NProgress.start()
    document.title = getTitle(to.meta?.title)
    const isLogin = !!Storage.getStorage(TOKEN_KEY) // 判断是否登录
    if (isLogin) {
      if (to.path === '/login') {
        // 已登录，访问登录页，跳转到首页
        next({ path: '/' })
      } else {
        const permissionStore = usePermissionStore()
        // 判断路由是否加载过
        if (permissionStore.isRoutesLoaded) {
          if (to.matched.length === 0) {
            // 路由未匹配，跳转到404
            next('/404')
          } else {
            // 动态设置页面标题
            // const title = (to.params.title as string) || (to.query.title as string)
            // if (title) {
            //   to.meta.title = title
            // }
            next()
          }
        } else {
          try {
            // 生成动态路由
            const dynamicRoutes = await permissionStore.generateRoutes()
            dynamicRoutes.forEach((route: RouteRecordRaw) => router.addRoute(route))
            next({ ...to, replace: true }) // 添加动态路由后重新导航
          } catch (error) {
            console.error(error)
            // 路由加载失败，重置 token 并重定向到登录页
            await useUserStore().clearUserSession()
            redirectToLogin(to, next)
            NProgress.done()
          }
        }
      }
    } else {
      // 未登录，判断是否在白名单中
      if (whiteList.includes(to.path)) {
        next()
      } else {
        // 不在白名单，重定向到登录页
        redirectToLogin(to, next)
        NProgress.done() // 关闭进度条
      }
    }
  })

  // 后置守卫，保证每次路由跳转结束时关闭进度条
  router.afterEach(() => {
    NProgress.done()
  })
}

function getTitle(pageTitle: string) {
  if (pageTitle) {
    return `${pageTitle} - ${defaultSettings.title}`
  }
  return `${defaultSettings.title}`
}
